#pragma once
#ifndef RENDERABLE_VERTEXS_H
#define RENDERABLE_VERTEXS_H
#include <d3d9.h>
#include "GraphicsManager.h"
#include "VertexTypes.h"

class CRenderableVertexs
{
	protected:
		LPDIRECT3DVERTEXBUFFER9 m_VB;
		LPDIRECT3DINDEXBUFFER9 m_IB;
		size_t m_IndexCount, m_VertexCount;
	public:
		CRenderableVertexs(): m_VB(NULL), m_IB(NULL), m_IndexCount(0), m_VertexCount(0){}
		virtual ~CRenderableVertexs() {CHECKED_RELEASE(m_VB); CHECKED_RELEASE(m_IB);}
		virtual bool Render(CGraphicsManager *GM) = 0;
		virtual inline size_t GetFacesCount() const {return m_IndexCount/3;};
		virtual inline size_t GetVertexsCount() const {return m_VertexCount;};
		virtual inline unsigned short GetVertexType() = 0;
		virtual inline size_t GetVertexSize() = 0;
		virtual inline size_t GetIndexSize() = 0;
};

template<class T>
class CIndexedVertexs : public CRenderableVertexs
{
	protected:
		inline size_t GetVertexSize() {return sizeof(T);}
		inline size_t GetIndexSize() {return sizeof(unsigned short);}
	public:
		CIndexedVertexs(CGraphicsManager *GM, void *VertexAddress, void *IndexAddres, size_t VertexCount, size_t IndexCount)
		{
			m_VertexCount = VertexCount;
			m_IndexCount = IndexCount;
			if( FAILED( GM->GetDevice()->CreateVertexBuffer( m_VertexCount*GetVertexSize(), 0 /*Usage*/, T::GetFVF(), D3DPOOL_DEFAULT, &m_VB, NULL ) ) )
				assert(E_FAIL);

			void* pVertices;

			if(FAILED(m_VB->Lock(0, m_VertexCount*GetVertexSize(), (void **)&pVertices, 0 ) ) ) 
				assert(E_FAIL);

			memcpy(pVertices, VertexAddress, GetVertexSize()*m_VertexCount);
			m_VB->Unlock();
	
			if( FAILED( GM->GetDevice()->CreateIndexBuffer( m_IndexCount*GetIndexSize(),	0 /*Usage*/, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_IB, NULL ) ) )
				assert(E_FAIL);

			void * pIndex;

			if(FAILED(m_IB->Lock(0, GetIndexSize()*m_IndexCount, (void **)&pIndex, 0 ) ) ) 
				assert(E_FAIL);

			memcpy(pIndex, IndexAddres, GetIndexSize()*m_IndexCount);
			m_IB->Unlock();
		}
		~CIndexedVertexs()
		{
		}
		virtual bool Render(CGraphicsManager *GM)
		{
			GM->GetDevice()->SetFVF(T::GetFVF());
			GM->GetDevice()->SetStreamSource(0, m_VB, 0, GetVertexSize());
			GM->GetDevice()->SetIndices(m_IB);
			GM->GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_VertexCount, 0, GetFacesCount());
			return true;
		}
		virtual inline unsigned short GetVertexType() {return T::GetVertexType();}
};
#endif